package main.java.chessfootball.model.game;

import main.java.chessfootball.model.play.Move;
import main.java.chessfootball.model.play.Put;
import main.java.chessfootball.model.regulation.Period;

/**
 * User: Igor
 * Date: 10.06.2011
 * Time: 21:48:06
 */
public class Field
{
	public static final int WIDTH = 18;
	public static final int LENGTH = 30;

	public static final Area GAME_AREA = new Area(0, 0, LENGTH, WIDTH);
	public static final Area[] GOALS_AREA = {new Area(0, 7, 1, 4), new Area(29, 7, 1, 4)};
	public static final Area PLAY_AREA = new Area(1, 1, 28, 16);
	public static final Area[] HALF_WAY_AREA = {new Area(0, 0, 15, 18), new Area(15, 0, 15, 18)};
	public static final Area[] PENALTY_AREA = {new Area(1, 4, 5, 10), new Area(24, 4, 5, 10)};
	public static final Area[] KEEPER_AREA = {new Area(1, 6, 2, 6), new Area(27, 6, 2, 6)};
	public static final Area CENTRE_CIRCLE_AREA = new Area(11, 5, 8, 8);
	public static final Area[] HALF_CENTRE_CIRCLE_AREA = {new Area(11, 5, 4, 8), new Area(15, 5, 4, 8)};
	public static final Cell[] CENTRE_SPOT = {new Cell(14, 8), new Cell(15, 9)};
	public static final Cell[] PENALTY_SPOT = {new Cell(4, 8), new Cell(25, 9)};
	public static final Cell[] LEFT_CK_SPOT = {new Cell(1, 1), new Cell(28, 16)};
	public static final Cell[] RIGHT_CK_SPOT = {new Cell(1, 16), new Cell(28, 1)};
	public static final Area[] INVERT_HALF_WAY_AREA = {Field.HALF_WAY_AREA[1], Field.HALF_WAY_AREA[0]};


	private Ball ball;
	private Team[] teams = new Team[2];

	public Field()
	{
		ball = new Ball(0, 0);
	}

	public Field(Ball ball, Team team1, Team team2)
	{
		this.ball = ball;
		teams[0] = team1;
		teams[1] = team2;
	}

	public void start(Half startHalf, Side startSide, Uniform uniform, int playersCount, Period period)
	{
		ball.put(period.getStartBallPosition()[startHalf.getId()]);
		teams[startSide.getId()] = new Team(startSide, uniform, startHalf, new Player[playersCount]);
		teams[startSide.getInvert().getId()] = new Team(startSide.getInvert(), uniform.getInvert(),
				startHalf.getInvert(), new Player[playersCount]);
	}

	public void move(Move move)
	{
		Player player = getPlayer(move.getSide(), move.getPlayer());
		if (move.getVector().getCell(player.getCell(), 1).equals(ball.getCell()))
		{
			ball.move(move.getVector(), move.getLength());
		}
		player.move(move.getVector());
	}

	public void put(Put put)
	{
		Player player = getPlayer(put.getSide(), put.getPlayer());
		if (player == null)
		{
			getTeam(put.getSide()).setPlayer(put.getPlayer(), put.getCell());
		}
		else
		{
			player.put(put.getCell());
		}
	}

	public void arrangement(Side startSide, Period period)
	{
		start(teams[startSide.getId()].getHalf(), startSide
				, teams[startSide.getId()].getUniform()
				, teams[startSide.getId()].getPlayers().length
				, period);
	}

	public void changeHalf()
	{
		for (Team team : teams)
		{
			team.setHalf(team.getHalf().getInvert());
		}
	}

	public boolean ballInGoal()
	{
		for (Half half : Half.values())
		{
			if (GOALS_AREA[half.getId()].contains(ball.getCell()))
			{
				return true;
			}
		}
		return false;
	}

	public Side getSideOfGoal()
	{
		for (Team team : teams)
		{
			if (GOALS_AREA[team.getHalf().getId()].contains(ball.getCell()))
			{
				return team.getSide().getInvert();
			}
		}
		return null;
	}


	public Player getPlayer(Side side, int number)
	{
		return getTeam(side).getPlayers()[number-1];
	}

	public Player getPlayer(Cell cell)
	{
		Player player = getTeam(Side.HOME).getPlayer(cell);
		if (player != null)
		{
			return player;
		}
		else
		{
			return getTeam(Side.OPPOSING).getPlayer(cell);
		}
	}

	public Ball getBall()
	{
		return ball;
	}

	public Team getTeam(Side side)
	{
		return teams[side.getId()];
	}

	public void formation(String snapshot)
	{
		StringBuilder sb = new StringBuilder(snapshot);
		String[] strR = new String[20];
		int end = 0;
		String s = sb.toString();
		for (int k = 0; k < strR.length; k++)
		{
//			start = 65 * k;
//			end = 65 * (k + 1);
			end = sb.indexOf("\n");
			strR[k] = s.substring(0, end - 1);
			s = s.substring(end + 1);
		}
		for (int k = 2; k < strR.length; k++)
		{
			String str = strR[k];
			for (int i = 0; i < strR[k].length(); i++)
			{
				int x = (i - 3) / 2;
				int y = k - 2;
				if ((x >= 0)&&(x < 30)&&(y >= 0)&&(y < 18))
				{
					char c = str.charAt(i);
					for (Side side : Side.values())
					{
						if (teams[side.getId()].getUniform().getPrints().contains("" + c))
						{
							teams[side.getId()].setPlayer(teams[side.getId()].getUniform().getPrints().indexOf("" + c) + 1, new Cell(x, y));
						}
					}
					if ('o' == c)
					{
						ball = new Ball(x, y);
					}
				}	
			}
		}
	}

	@Override
	public String toString()
	{
		StringBuilder sb = new StringBuilder();

		sb.append("   ");
		for (int nx = 0; nx < LENGTH; nx++)
		{
			sb.append(" ");
			int i = nx / 10;
			if (i > 0)
			{
				sb.append(i);
			}
			else
			{
				sb.append(" ");
			}
		}
		sb.append(" \n");
		sb.append("   ");
		for (int nx = 0; nx < LENGTH; nx++)
		{
			sb.append(" ");
			sb.append((nx) % 10);
		}
		sb.append(" \n");

		for (int ky = 0; ky < WIDTH; ky++)
		{
			if (ky < 10)
			{
				sb.append(" ");
			}
			sb.append(ky);
			sb.append(" ");

			for (int kx = 0; kx < LENGTH + 1; kx++)
			{
				Cell cell = new Cell(kx, ky);
				if (PLAY_AREA.contains(cell)
						|| (GOALS_AREA[0].contains(cell))
						|| (GOALS_AREA[1].contains(cell)))
				{
					sb.append("|");
				}
				else if (((PLAY_AREA.getX2() == (cell.getX() - 1)) && (PLAY_AREA.containsByY(cell)))
						|| ((GOALS_AREA[1].getX2() == (cell.getX() - 1)) && (GOALS_AREA[1].containsByY(cell)))
						)
				{
					sb.append("|");
				}
				else
				{
					sb.append(" ");
				}

				if (cell.equals(ball.getCell()))
				{
					sb.append("o");
				}
				else if (teams[0].contains(cell))
				{
					sb.append(teams[0].getUniform().getPrints().get(teams[0].getPlayer(cell).getNumber()-1));
				}
				else if (teams[1].contains(cell))
				{
					sb.append(teams[1].getUniform().getPrints().get(teams[1].getPlayer(cell).getNumber()-1));
				}
				else if ((PLAY_AREA.containsByX(cell)
						&& ((PLAY_AREA.getY() == (cell.getY() + 1))
						|| (PLAY_AREA.getY2() == (cell.getY()))))
						|| ((GOALS_AREA[0].containsByX(cell))
						&& ((GOALS_AREA[0].getY() == (cell.getY() + 1))
						|| (GOALS_AREA[0].getY2() == (cell.getY()))))
						|| ((GOALS_AREA[1].containsByX(cell))
						&& ((GOALS_AREA[1].getY() == (cell.getY() + 1))
						|| (GOALS_AREA[1].getY2() == (cell.getY()))))
						|| ((CENTRE_CIRCLE_AREA.containsByX(cell))
						&& ((CENTRE_CIRCLE_AREA.getY() == (cell.getY() + 1))
						|| (CENTRE_CIRCLE_AREA.getY2() == (cell.getY()))))
						|| ((PENALTY_AREA[0].containsByX(cell))
						&& ((PENALTY_AREA[0].getY() == (cell.getY() + 1))
						|| (PENALTY_AREA[0].getY2() == (cell.getY()))))
						|| ((PENALTY_AREA[1].containsByX(cell))
						&& ((PENALTY_AREA[1].getY() == (cell.getY() + 1))
						|| (PENALTY_AREA[1].getY2() == (cell.getY()))))
						|| ((KEEPER_AREA[0].containsByX(cell))
						&& ((KEEPER_AREA[0].getY() == (cell.getY() + 1))
						|| (KEEPER_AREA[0].getY2() == (cell.getY()))))
						|| ((KEEPER_AREA[1].containsByX(cell))
						&& ((KEEPER_AREA[1].getY() == (cell.getY() + 1))
						|| (KEEPER_AREA[1].getY2() == (cell.getY()))))
						)
				{
					sb.append("_");
				}
				else
				{
					if (kx < LENGTH)
					{
						sb.append(" ");
					}
				}
			}

			sb.append("\n");
		}

		return sb.toString();
	}
}
